#pragma once

#include "../DefinesCore.hpp"
#include <string>

#ifdef CYBERTRON_WIN
#include <windows.h>
#elif CYBERTRON_LINUX
// #include <sys/ipc.h>
// #include <sys/shm.h>
#include <string.h>
#include <unistd.h>
// #include <cstdlib>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <semaphore.h>
#endif

CYBERTRON_BEGIN

struct SharedMemoryHandle
{
	std::string label;
	int size;
#ifdef CYBERTRON_WIN
	HANDLE handle;
	LPVOID lp;
#elif CYBERTRON_LINUX
    int fd;
	void *p;
#endif
};

#ifdef CYBERTRON_WIN
class SharedMemorySender
{
public:
    SharedMemorySender(const std::string& label, int size);
    ~SharedMemorySender();

    bool Send(const char* data);

private:
    SharedMemoryHandle mMapFile;
};

class SharedMemoryReceiver
{
public:
    SharedMemoryReceiver(const std::string& label, int size);
    ~SharedMemoryReceiver();

    bool Receive(char* data);

private:
    void OpenFileMap();

    SharedMemoryHandle mMapFile;
};
#endif

// below code for windows does not work well, do not use it on windows
class SharedMemory
{
public:
	static bool sharedMemoryCreateImpl(std::string label, int size, SharedMemoryHandle& handle);
	static void sharedMemoryDestroyImpl(SharedMemoryHandle& handle);
	static bool sharedMemoryWriteImpl(std::string label, int size, const char* data);
	static bool sharedMemoryReadImpl(std::string label, int size, char* data);
	static bool sharedMemoryExistImpl(std::string label);
};

#define SharedMemoryCreate cybertron::SharedMemory::sharedMemoryCreateImpl
#define SharedMemoryDestroy cybertron::SharedMemory::sharedMemoryDestroyImpl
#define SharedMemoryWrite cybertron::SharedMemory::sharedMemoryWriteImpl
#define SharedMemoryRead cybertron::SharedMemory::sharedMemoryReadImpl
#define SharedMemoryExist cybertron::SharedMemory::sharedMemoryExistImpl

CYBERTRON_END
